using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Campus.Entities;
using CampusSite.Models;
using CampusSite.ViewModels;
using MvcPaging;
using CampusSite.Security;
namespace CampusSite.Controllers
{
    [RolActionFilter]
    [RoleAuthorize(Constantes.RolAdministrador)]
    public class GruposController : Controller
    {

        private readonly IEquipoRepository equiposRepository;
		private readonly IActividadRepository actividadRepository;
		private readonly IGrupoRepository grupoRepository;
        private readonly ITurnoRepository   turnoRepository;
        private readonly IDiaDeLaSemanaRepository diaDeLaSemanaRepository;
        private readonly IProfesorRepository profesorRepository;
        private readonly IEstudianteRepository estudianteRepository;


        CampusSiteContext context;
		// If you are using Dependency Injection, you can delete the following constructor
        //public GruposController() : this(new ActividadRepository(), new GrupoRepository(), new TurnoRepository(), new DiaDeLaSemanaRepository(), new ProfesorRepository())
        //{
        //}

        public GruposController()                           
        {

            ViewBag.ActiveMenu = "Grupos";

            context = new CampusSiteContext();
            this.equiposRepository = new EquipoRepository(context);
            this.actividadRepository = new ActividadRepository();
			this.grupoRepository = new GrupoRepository(context);
            this.turnoRepository = new TurnoRepository(context);
            this.diaDeLaSemanaRepository = new DiaDeLaSemanaRepository(context);
            this.profesorRepository = new ProfesorRepository(context);
            this.estudianteRepository = new EstudianteRepository(context);
            
        }

        public GruposController(IActividadRepository actividadRepository, IGrupoRepository grupoRepository, ITurnoRepository turnoRepository, IDiaDeLaSemanaRepository diaDeLaSemanaRepository, IProfesorRepository profesorRepository, IEstudianteRepository estudianteRepository)
        {
			this.actividadRepository = actividadRepository;
			this.grupoRepository = grupoRepository;
            this.turnoRepository = turnoRepository;
            this.diaDeLaSemanaRepository = diaDeLaSemanaRepository;
            this.profesorRepository = profesorRepository;
            this.estudianteRepository = estudianteRepository;            
        }

        //
        // GET: /Grupos/

        public ViewResult Index(int? id)
        {
            List<Grupo> grupos ;            
            grupos = grupoRepository.AllIncluding(grupo => grupo.Turnos, grupo => grupo.Profesores, grupo => grupo.Actividad).OrderBy(g => g.Nombre).ToList<Grupo>();           

            ViewBag.IndexGrupoElegido = null;

            //si viene -1 son grupos de torneos NO buena FE
            if (id != null && id == -1)
            {
                grupos = grupos.Where(g => g.Actividad.ActividadId == 2 && g.EsListaBuenaFe == false).ToList();
                ViewBag.IndexGrupoElegido = id;                
            }

            
            //si viene -1 son grupos de torneos Lista buena FE
            if (id != null && id == -2)
            {
                grupos = grupos.Where(g => g.Actividad.ActividadId == 2 && g.EsListaBuenaFe == true).ToList();
                ViewBag.IndexGrupoElegido = id;
            }


            //si viene -3 son grupos de escuelita
            if (id != null && id == -3)
            {
                grupos = grupos.Where(g => g.Actividad.ActividadId == 1 && g.EsListaBuenaFe == false).ToList();
                ViewBag.IndexGrupoElegido = id;
            }

            BuscarGrupoElegido(id);      
            return View("Index",grupos);
            
        }




        public ViewResult IndexGruposTodos(int? id)
        {

            ViewBag.ActiveMenu = "IndexGruposTodos";
            return Index(null);                        
        }


        public ViewResult IndexGruposEscuelaDeFutbol(int? id)
        {
            ViewBag.ActiveMenu = "IndexGruposEscuelaDeFutbol";
            return Index(-3);                        
        }

        public ViewResult IndexGruposListaBuenaFe(int? id)
        {
            ViewBag.ActiveMenu = "IndexGruposListaBuenaFe";
            return Index(-2);            
        }

        public ViewResult IndexGruposDeTorneo(int? id)
        {
            ViewBag.IndexGruposListaBuenaFe = "IndexGruposDeTorneo";
            return Index(-1);            
        }


        private void BuscarGrupoElegido(int? id)
        {
            if (id != null && id != 0 && id != -1 && id != -2 && id != -3)
            {
                Grupo grupo = grupoRepository.Find((int)id);
                ViewBag.Estudiantes = grupo.Estudiantes;
                ViewBag.Grupo = grupo;
            }
        }
        

        //
        // GET: /Grupos/Details/5

        public ViewResult Details(int id, int? indexGrupoElegido)
        {
            SetViewBag(indexGrupoElegido);

            var grupo = grupoRepository
                  .AllIncluding(g => g.Profesores, g => g.Turnos)
                  .Single(g => g.GrupoId == id);

            return View(grupo);
        }

        //
        // GET: /Grupos/Create

        public ActionResult Create(int? indexGrupoElegido)
        {
            SetViewBag(indexGrupoElegido);
                        
            return View();
        }

        private void SetTurnosView()
        {
            
            ViewBag.DiasDeLaSemana = diaDeLaSemanaRepository.All;

            List<SelectListItem> horas = new List<SelectListItem>();            

            for (byte hora = 00; hora < 25; hora++)
                horas.Add(new SelectListItem 
                            { Value = hora.ToString().PadLeft(2,'0'), 
                               Text = hora.ToString().PadLeft(2, '0') });

            List<SelectListItem> minutos = new List<SelectListItem>();
            //minutos.Add(new SelectListItem { Text = "Elija un valor", Value = "-1" });
            for (byte min = 00; min < 60; min += 5)
                minutos.Add(new SelectListItem { Value = min.ToString().PadLeft(2, '0'), Text = min.ToString().PadLeft(2, '0') });

            ViewBag.Horas = horas;
            ViewBag.Minutos = minutos;
        } 

        //
        // POST: /Grupos/Create

        [HttpPost]
        public ActionResult Create(ICollection<Turno> turnos, Grupo grupo,  ICollection<Profesor> profesores, ICollection<Estudiante> estudiantes)
        {
            ViewBag.IndexGrupoElegido = int.Parse(Request.QueryString["IndexGrupoElegido"]);
            if (ModelState.IsValid)
            {                            
                Grupo grupoNuevo = new Grupo();
                grupoNuevo.Nombre = grupo.Nombre;
                //grupoNuevo.ActividadId = grupo.ActividadId;
                //grupoNuevo.EsListaBuenaFe = grupo.EsListaBuenaFe;

                //si es escuelita de futbol inserto actividad 1 escuelita sino 2, torneo.
                grupoNuevo.ActividadId = ViewBag.IndexGrupoElegido == -3 ? 1 : 2;

                grupoRepository.InsertOrUpdate(grupoNuevo);
                grupoRepository.Save();
                
                grupo.GrupoId = grupoNuevo.GrupoId;
                
                
                CreateOrUpdateGroup(grupo, ViewBag.IndexGrupoElegido);
                  
                return RedirectToAction("Index", new { id = ViewBag.IndexGrupoElegido });
            }
            
            else
            {
                SetViewBag(ViewBag.IndexGrupoElegido);

                return View(grupo);
            }
        }
        
        //
        // GET: /Grupos/Edit/5

        public ActionResult Edit(int id, int? indexGrupoElegido)
        {
            SetViewBag(indexGrupoElegido);

            var grupo = grupoRepository
                  .AllIncluding(g => g.Profesores, g => g.Turnos)                  
                  .Single(g => g.GrupoId == id);
             
             return View(grupo);
        }

        private void SetViewBag(int? indexGrupoElegido)
        {

            ViewBag.PossibleProfesores = profesorRepository.All;
            ViewBag.PossibleActividads = actividadRepository.All;
            ViewBag.PossibleEquipos = equiposRepository.All.OrderBy(e=> e.Nombre);
            ViewBag.PossibleEquiposRivales = equiposRepository.All.OrderBy(e => e.Nombre);

            ViewBag.IndexGrupoElegido = indexGrupoElegido;
            
            SetTurnosView();
        }

        //
        // POST: /Grupos/Edit/5

        [HttpPost]
        public ActionResult Edit(Grupo grupo)
        {

            ViewBag.IndexGrupoElegido = int.Parse(Request.QueryString["IndexGrupoElegido"]);
            
            if (ModelState.IsValid)
            {
                CreateOrUpdateGroup(grupo, ViewBag.IndexGrupoElegido);

                return RedirectToAction("Index", new { id = ViewBag.IndexGrupoElegido } );
            }
            else
            {
                SetViewBag(ViewBag.IndexGrupoElegido);
                return View(grupo);
            }
        }



        /// <summary>
        /// Crea o actualiza un grupo. 
        /// </summary>
        /// <param name="grupo"></param>
        private void CreateOrUpdateGroup(Grupo grupo, int tipoGrupo)
        {

            //TODO: Intentar llevar el metodo al repositorio, resolviendo el problema de distintos contextos

            int id = grupo.GrupoId;
            var item = grupoRepository
                              .AllIncluding(g => g.Profesores, g => g.Turnos, g => g.Estudiantes, g => g.Actividad  )
                              .Single(g => g.GrupoId == id);
            
            grupo.ActividadId = item.ActividadId;
            
            grupoRepository.ChangeScalarValues(item, grupo);

            if (item != null)
            {
                //si es lista buena fe le pongo true sino false.
                if (tipoGrupo == -2)
                    item.EsListaBuenaFe = true;
                else
                    item.EsListaBuenaFe = false;


                //Borro los profesores.
                item.Profesores.Clear();
                if (grupo.Profesores != null)
                {
                    
                    //TODO: Ver que se puede mejorar no borrando todo.                                    
                    foreach (var p in grupo.Profesores)
                    {
                        var profesor = profesorRepository.Find(p.ProfesorId);
                        item.Profesores.Add(profesor);
                    }
                }

                turnoRepository.RemoveByGrupo(item.GrupoId);
                if (grupo.Turnos != null)
                {                
                    foreach (var t in grupo.Turnos)
                    {
                        Turno turno = new Turno()
                        {
                            Grupo = item,
                            HoraFin = t.HoraFin,
                            HoraInicio = t.HoraInicio
                        };

                        turno.DiaDeLaSemana = diaDeLaSemanaRepository.Find(t.DiaDeLaSemana.DiaDeLaSemanaId);
                        turnoRepository.InsertOrUpdate(turno);
                    }
                }

                //Estudiantes 
                item.Estudiantes.Clear();
                if (grupo.Estudiantes != null)
                {               
                    //Inserto los nuevos turnos
                    foreach (var est in grupo.Estudiantes)
                    {
                        var estudiante = estudianteRepository.Find(est.EstudianteId);
                        item.Estudiantes.Add(estudiante);
                    }
                }

                grupoRepository.InsertOrUpdate(item);
                grupoRepository.Save();
              }
        }
                      
        // GET: /Grupos/Delete/5

        public ActionResult Delete(int id, int? indexGrupoElegido)
        {
            SetViewBag(null);

            var grupo = grupoRepository
                  .AllIncluding(g => g.Profesores, g => g.Turnos)
                  .Single(g => g.GrupoId == id);

            return View(grupo);

        }


        //
        // POST: /Grupos/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {

            ViewBag.IndexGrupoElegido = int.Parse(Request.QueryString["IndexGrupoElegido"]);

            bool grupoTieneProfesOEstudiantes = grupoRepository.AllIncluding(g => g.Profesores, g => g.Estudiantes).Any(g => g.GrupoId == id && (g.Profesores.Count > 0 || g.Estudiantes.Count > 0));


            if (grupoTieneProfesOEstudiantes)
            {                
                ModelState.AddModelError("NoPuedeEliminarGrupo", "No podra eliminar el grupo porque existen profesores o estudiantes asociados");
                return View(grupoRepository.Find(id));
            }
            else
            {
                grupoRepository.Delete(id);
                grupoRepository.Save();
            }
            return RedirectToAction("Index", new { id = ViewBag.IndexGrupoElegido });
        }

        public ActionResult QuickSearch(string term)
        {
            var estudiantes = estudianteRepository.GetEstudiantesByName(term).Select(e => new {id = e.EstudianteId, label = (e.Apellido + ", " + e.Nombre + " (" + e.FechaNacimiento.Year.ToString() + ")"), nombre = e.Nombre, apellido = e.Apellido });

            ViewBag.Estudiantes = estudiantes.ToList().ToPagedList(0, 10);
            return Json(estudiantes, JsonRequestBehavior.AllowGet);
        }

        

        protected override void Dispose(bool disposing)
        {
            if (disposing) {
                actividadRepository.Dispose();
                profesorRepository.Dispose();
                grupoRepository.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

